/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.pig.pigpen.editor.editparts;

import java.beans.PropertyChangeEvent;
import java.io.File;
import java.io.IOException;
import java.util.List;

import org.apache.pig.pigpen.LoggerUtil;
import org.apache.pig.pigpen.editor.PigQueryEditor;
import org.apache.pig.pigpen.editor.layout.GraphLayoutManager;
import org.apache.pig.pigpen.editor.model.Link;
import org.apache.pig.pigpen.editor.model.Operator;
import org.apache.pig.pigpen.editor.model.Query;
import org.apache.pig.pigpen.editor.policies.QueryLayoutEditPolicy;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.FlowLayout;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.ToolbarLayout;
import org.eclipse.draw2d.graph.DirectedGraphLayout;
import org.eclipse.gef.EditPolicy;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IPathEditorInput;

public class QueryEditPart extends PropertyAwarePart {

    private PigQueryEditor editor;

    public QueryEditPart(PigQueryEditor editor) {
        this.editor = editor;

        // start an empty query
        setModel(new Query());
    }

    // load a query from a .pig file
    public void loadFile(IEditorInput input) throws IOException {
        try {
            File file = ((IPathEditorInput) input).getPath().toFile();

            getModel().loadFile(file);
            refreshVisuals();
        } catch (IOException e) {
            getModel().removeAllComponents();
            setModel(new Query());
            LoggerUtil.logError("Error loading pig file", e);
            popupMessage("Error loading pig file:\n\n" + e.getMessage());
            throw e;
        }
    }

    public void popupMessage(String msg) {
        MessageDialog.openInformation(getViewer().getControl().getShell(),
                "Pig Pen Warning", msg);
    }

    @Override
    protected IFigure createFigure() {
        Figure f = new Figure();
        f.setOpaque(true);
        f.setLayoutManager(new GraphLayoutManager(this));

        return f;
    }

    @Override
    protected void createEditPolicies() {
        installEditPolicy(EditPolicy.LAYOUT_ROLE, new QueryLayoutEditPolicy());
    }

    public void propertyChange(PropertyChangeEvent evt) {
        super.propertyChange(evt);

        String property = evt.getPropertyName();
        Object newValue = evt.getNewValue();
        Object oldValue = evt.getOldValue();

        if (Query.LINK.equals(property)) {
            if (newValue != null) {
                Link link = (Link) newValue;
                for (Object child : this.getChildren()) {
                    if (child instanceof OperatorEditPart) {
                        OperatorEditPart opPart = (OperatorEditPart) child;
                        Operator op = opPart.getModel();
                        if (op == link.getSource()) {
                            opPart.refresh(); // to pick up the new link from
                                              // the model
                        }
                        if (op == link.getTarget()) {
                            opPart.refresh(); // to pick up the new link from
                                              // the model
                        }
                    }
                }
            } else if (oldValue != null) {
                Link link = (Link) oldValue;
                for (Object child : this.getChildren()) {
                    if (child instanceof OperatorEditPart) {
                        OperatorEditPart opPart = (OperatorEditPart) child;
                        Operator op = opPart.getModel();
                        if (op == link.getSource()) {
                            opPart.refresh(); // to pick up the fact that the
                                              // link no longer appears in the
                                              // model
                        }
                        if (op == link.getTarget()) {
                            opPart.refresh(); // to pick up the fact that the
                                              // link no longer appears in the
                                              // model
                        }
                    }
                }
            }
        } else if (Query.HEADER.equals(property)) {
            editor.setDirty(true);
            editor.refreshHeaderPage();
        }
    }

    protected List getModelChildren() {
        return getModel().getOperators();
    }

    public Query getModel() {
        return (Query) super.getModel();
    }

    protected void refreshVisuals() {
        getFigure().repaint();
    }
}
